﻿//----------------------------------------------------------------------------------------
// Copyright (C) 2008  银龙小子 版权所有。
//
// 文件编号：      
// 文 件 名：      DataBaseBuild.cs
// 文件功能描述：   MaoCaiJun.DataBase的处理类
//
// 创建标识：      毛才君    2008-3-22 13:01:03
//
// 修改标识：
// 修改描述：
// 
// 修改标识：
// 修改描述：
//----------------------------------------------------------------------------------------
using System.Xml;
using System.IO;
using System.CodeDom;
using Microsoft.CSharp;
using System.CodeDom.Compiler;
using System.Reflection;
using MaoCaiJun.DataBase.BuildProviders.Common;
using MaoCaiJun.DataBase.BuildProviders.BuildClass.Access;

namespace MaoCaiJun.DataBase.BuildProviders
{
    /// <summary>
    /// 源代码生成工厂类
    /// </summary>
public    class DataBaseBuild
    {
        /// <summary>
        /// 源代码生成工厂
        /// </summary>
        /// <param name="inStream">DBS文件流.</param>
        /// <param name="codePath">生成代码路径.</param>
        /// <returns></returns>
        public static CodeCompileUnit Build(Stream inStream, string codePath)
        {
          return Build(new Configuration.DbsAnalysis.MaoCaiJunDataBaseMapping( inStream), codePath);
           
        }
        /// <summary>
        /// 源代码生成工厂
        /// </summary>
        /// <param name="filename">DBS文件路径.</param>
        /// <param name="codePath">生成代码路径.</param>
        /// <returns></returns>
        public static CodeCompileUnit Build(string filename, string codePath)
        {
            return Build(new Configuration.DbsAnalysis.MaoCaiJunDataBaseMapping(filename), codePath);
        }
        /// <summary>
        /// 源代码生成工厂
        /// </summary>
        /// <param name="txtReader">DBS文件流.</param>
        /// <param name="codePath">生成代码路径.</param>
        /// <returns></returns>
        public static CodeCompileUnit Build(TextReader txtReader, string codePath)
        {
            return Build(new Configuration.DbsAnalysis.MaoCaiJunDataBaseMapping(txtReader), codePath);
        }
        /// <summary>
        /// 源代码生成工厂
        /// </summary>
        /// <param name="reader">DBS文件流.</param>
        /// <param name="codePath">生成代码路径.</param>
        /// <returns></returns>
        public static CodeCompileUnit Build(XmlReader reader, string codePath)
        {
            return Build(new Configuration.DbsAnalysis.MaoCaiJunDataBaseMapping(reader), codePath);
        }

        /// <summary>
        /// 源代码生成工厂
        /// </summary>
        /// <param name="dbsAnalysis">生成代码路径.</param>
        /// <param name="codePath">生成代码路径</param>
        /// <returns></returns>
        private static CodeCompileUnit Build(Configuration.DbsAnalysis.MaoCaiJunDataBaseMapping dbsAnalysis, string codePath)
        {
            CodeCompileUnit ccu = new CodeCompileUnit();

            #region 类
            //if (System.IO.File.Exists(codePath)) { System.IO.File.Delete(codePath); }
            string resCode = string.Empty;
            foreach (MaoCaiJun.DataBase.Configuration.DbsAnalysis.Namespace dbsAnalysisNamespace in dbsAnalysis.Namespace)
            {
                foreach (MaoCaiJun.DataBase.Configuration.DbsAnalysis.Class item in dbsAnalysisNamespace.Class)
                {
                    #region 特殊功能处理
                    switch (item.Function)
                    {
                        case MaoCaiJun.DataBase.Sys.Data.FunctionType.Catalog:
                            if (item.Type == MaoCaiJun.DataBase.Sys.Data.SqlType.Sqlite)
                            {
                                new Function.CatalogSqlite(item);
                            }
                            else
                            {
                                new Function.Catalog(item);
                            }
                            break;
                        case MaoCaiJun.DataBase.Sys.Data.FunctionType.News:
                            new Function.News(item);
                            break;
                        case MaoCaiJun.DataBase.Sys.Data.FunctionType.Download:
                            new Function.Download(item);
                            break;
                    }
                    #endregion 特殊功能处理

                    if (item.Type ==MaoCaiJun.DataBase.Sys.Data.SqlType.Sql2008)
                    {
                        new BuildClass.Sql2005.BuildDbSqlClass(item);// 编译数据访问层

                    }
                    else if (item.Type == MaoCaiJun.DataBase.Sys.Data.SqlType.Sql2005)
                    {
                        new BuildClass.Sql2005.BuildDbSqlClass(item);// 编译数据访问层

                    }
                    else if (item.Type == MaoCaiJun.DataBase.Sys.Data.SqlType.Sql2000)
                    {
                        new BuildClass.Sql2005.BuildDbSqlClass(item);// 编译数据访问层

                    }
                    else if (item.Type == MaoCaiJun.DataBase.Sys.Data.SqlType.Access)
                    {
                        new BuildClass.Access.BuildDalAccessClass(item);// 编译数据访问层
                    }
                    else if (item.Type == MaoCaiJun.DataBase.Sys.Data.SqlType.Sqlite)
                    {
                        new BuildClass.Sqlite.BuildDalSqliteClass(item);// 编译数据访问层
                    }
                    else if (item.Type == MaoCaiJun.DataBase.Sys.Data.SqlType.MySql)
                    {
                        new BuildClass.MySql.BuildDalMySqlClass(item);// 编译数据访问层
                    }
                    else
                    {
                        throw new System.Exception(item.Name + " 中 找不到指定的数据库类型");
                    }

                    new BuildModelClass(item);// 编译实体类
                    new BuildModelEnum(item);
                    resCode += BuildResClass.GetResCode(item, codePath);
                    //new MaoCaiJun.DataBase.BuildProviders.Common.CreateClassDoc(item, dataDoc); //生成文档

                    ccu.Namespaces.Add(item.Namespace.GetNamespace());
                }
            }

            if (!System.IO.File.Exists(codePath))
            {
                StreamWriter sssss = new StreamWriter(codePath, false, System.Text.Encoding.Default);
                sssss.WriteLine(resCode);
                sssss.Close();
            }
            #endregion 类

            return ccu;
        }

        //private static CodeCompileUnit Build(DbsAnalysis dbsAnalysis, string codePath)
        //{
        //    CodeCompileUnit ccu = new CodeCompileUnit();

        //    #region 类
        //    //if (System.IO.File.Exists(codePath)) { System.IO.File.Delete(codePath); }
        //    string resCode = string.Empty;
        //    foreach (MaoCaiJun.DataBase.Configuration.DbsAnalysis.Class item in dbsAnalysis.DbsClass)
        //    {
        //        #region 特殊功能处理
        //        switch (item.Function)
        //        {
        //            case "Catalog":
        //                new Function.Catalog(item);
        //                break;
        //            case "News":
        //                new Function.News(item);
        //                break;
        //            case "Download":
        //                new Function.Download(item);
        //                break;
        //        }
        //        #endregion 特殊功能处理

        //        if (item.Type.Trim() == "Sql2008")
        //        {
        //            new BuildClass.Sql.BuildDbSqlClass(item);// 编译数据访问层

        //        }
        //        if (item.Type.Trim() == "Sql2005")
        //        {
        //            new BuildClass.Sql.BuildDbSqlClass(item);// 编译数据访问层

        //        }
        //        else if (item.Type.Trim() == "Sql2000")
        //        {
        //            new BuildClass.Sql.BuildDbSqlClass(item);// 编译数据访问层

        //        }
        //        else if (item.Type.Trim() == "Access")
        //        {
        //            new BuildDalAccessClass(item);// 编译数据访问层
        //        }
        //        else
        //        {
        //            throw new System.Exception(item.Name + " 中 找不到指定的数据库类型");
        //        }

        //        new BuildModelClass(item);// 编译实体类
        //        new BuildModelEnum(item);
        //        resCode += BuildResClass.GetResCode(item, codePath);
        //        //new MaoCaiJun.DataBase.BuildProviders.Common.CreateClassDoc(item, dataDoc); //生成文档

        //        ccu.Namespaces.Add(item.Namespace);
        //    }

        //    if (!System.IO.File.Exists(codePath))
        //    {
        //        StreamWriter sssss = new StreamWriter(codePath, false, System.Text.Encoding.Default);
        //        sssss.WriteLine(resCode);
        //        sssss.Close();
        //    }
        //    #endregion 类

        //    return ccu;
        //}


        /// <summary>
        /// 返回代码
        /// </summary>
        /// <param name="codeCompileUnit">The code compile unit.</param>
        /// <returns></returns>
        public static string GenerateCode(CodeCompileUnit codeCompileUnit)
        {
            // 调用我们前面的方法创建CodeCompileUnit
            CodeCompileUnit ccu = codeCompileUnit;
            CSharpCodeProvider provider = new CSharpCodeProvider();
            CodeGeneratorOptions options = new CodeGeneratorOptions();
            options.BlankLinesBetweenMembers = false;
            options.IndentString = "\t";

            StringWriter sw = new StringWriter();
            provider.GenerateCodeFromCompileUnit(ccu, sw, options);
            sw.Flush();
            return sw.GetStringBuilder().ToString();
        }

        /// <summary>
        /// Compiles the in memory.
        /// </summary>
        /// <param name="codeCompileUnit">The code compile unit.</param>
        /// <returns></returns>
        public static Assembly CompileInMemory(CodeCompileUnit codeCompileUnit)
        {
            CSharpCodeProvider provider = new CSharpCodeProvider();
            CompilerParameters options = new CompilerParameters();
            //options.CompilerOptions = "/define:TRACE=1   /define:DEBUG=1   "; 
            options.IncludeDebugInformation = false;
            options.GenerateExecutable = false;
            options.GenerateInMemory = true;
            CompilerResults results = provider.CompileAssemblyFromDom(options, codeCompileUnit);
            provider.Dispose();
            Assembly generatedAssembly = null;
            if (results.Errors.Count == 0)
            {
                generatedAssembly = results.CompiledAssembly;
            }
            return generatedAssembly;
        }
    }
}